
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta charset="utf-8" />
    <title>Adding new calculation styles &#8212; iprPy 0.10.2 documentation</title>
    <link rel="stylesheet" href="../_static/basic.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
    <script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    <script type="text/x-mathjax-config">MathJax.Hub.Config({"tex2jax": {"inlineMath": [["$", "$"], ["\\(", "\\)"]], "processEscapes": true, "ignoreClass": "document", "processClass": "math|output_area"}})</script>
    <link rel="index" title="Index" href="../genindex.html" />
    <link rel="search" title="Search" href="../search.html" />
    <link rel="next" title="Adding new record styles" href="addrecord.html" />
    <link rel="prev" title="Reference Library" href="addreference.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="addrecord.html" title="Adding new record styles"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="addreference.html" title="Reference Library"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">iprPy 0.10.2 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Extending iprPy</a> &#187;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="adding-new-calculation-styles">
<h1>Adding new calculation styles<a class="headerlink" href="#adding-new-calculation-styles" title="Permalink to this headline">¶</a></h1>
<p>The basic steps associated with implementing a new calculation style in iprPy
are</p>
<ol class="arabic simple">
<li><p>Create a new subdirectory in iprPy/calculation named for the new calculation
style.  For the style name, use lowercase letters except where important and
separate words with underscores.  The name should be clear and distinct as
to what the calculation does.</p></li>
<li><p>Create the calculation script calc_[style].py within the calculation
style directory.</p></li>
<li><p>Add the Python function(s) that perform the calculation to the calculation
script.</p></li>
<li><p>Define a process_input() function within the script that generates the
inputs for the calculation function(s) based on a text input file.</p></li>
<li><p>If any sets of input keys can or are used by multiple calculation styles and
are not already collected in a subset style, think about creating one.</p></li>
<li><p>Add a main() function that calls process_input followed by the calculation
function(s).  Add the “if __name__ == ‘__main__’:” check that calls
main() and passes it any command line arguments.</p></li>
<li><p>Place copies of any other files that the calculation needs (excluding input
files) in the calculation folder.</p></li>
<li><p>Create a separate file that defines the Calculation subclass.  Name the file
after the subclass name, typically by converting the style name to upper
camel case (each word capitalized with no separators).</p></li>
<li><p>Define the subclass methods and attributes specific to the calculation
style.</p></li>
<li><p>Create an “__init__.py” file that imports the subclass.</p></li>
<li><p>Create a record style for collecting the calculation results (see
addrecord documentation).</p></li>
<li><p>Test single runs of the calculation using Calculation.calc(), and
Calculation.main() or by running the calculation script.</p></li>
<li><p>Test preparing the new calculation style for a limited number of conditions.</p></li>
<li><p>In a terminal, go into one of the prepared calculations in the run directory
and run the calculation script directly.  Doing this helps check that all
components of the calculation were properly copied during prepare.</p></li>
<li><p>Run all of the prepared calculations with runners and check the results.</p></li>
<li><p>Write documentation for the calculation style in the README.md, theory.md,
and parameters.md files.  Create an empty calc_[style].in input file.</p></li>
</ol>
<div class="section" id="files-in-the-calculation-style-directories">
<h2>Files in the calculation style directories<a class="headerlink" href="#files-in-the-calculation-style-directories" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
<li><p><strong>calc_[style].py</strong>: The Python calculation script.</p></li>
<li><p><strong>calc_[style].in</strong>: The input file for the calculation with all input keys
and no values.</p></li>
<li><p><strong>[Style].py</strong>: Defines the Calculation subclass for the calculation style.
This defines how the iprPy codebase interacts with the calculation.</p></li>
<li><p><strong>__init__.py</strong>: Allows Python to identify the calculation directory as
a sub-package and be able to import the calculation subclass into iprPy.</p></li>
<li><p><strong>README.md</strong>: A general overview description of the calculation.</p></li>
<li><dl class="simple">
<dt><strong>theory.md</strong>: A detailed description of the calculation theory and</dt><dd><p>methodology.</p>
</dd>
</dl>
</li>
<li><p><strong>parameters.md</strong>: Lists and describes the input parameters recognized by the
calculation style.</p></li>
<li><p>Copies of any other files required by the calculation.</p></li>
</ul>
<div class="section" id="calc-style-py">
<h3>calc_[style].py<a class="headerlink" href="#calc-style-py" title="Permalink to this headline">¶</a></h3>
<p>The calculation scripts have a number of components that are common across the
different styles.  This section lists those common components to assist with
the rapid implementation of new calculation styles.</p>
<div class="section" id="record-style">
<h4>record_style<a class="headerlink" href="#record-style" title="Permalink to this headline">¶</a></h4>
<p>The record style used by the calculation for constructing the results.json file
is listed at the top of the file just before defining the main() function.
While record_style does not need to be a global variable, it is useful to place
it here for clarity.</p>
</div>
<div class="section" id="main">
<h4>main()<a class="headerlink" href="#main" title="Permalink to this headline">¶</a></h4>
<p>The calculation script’s main() function</p>
<ol class="arabic simple">
<li><p>Opens and parses an input parameter file with the iprPy.input.parse()
function.  This returns a dictionary of the key-value terms, with the values
as strings.</p></li>
<li><p>Calls process_input() to interpret the string values of the input dictionary
as Python values and objects.  The interpreted values are added to the input
dictionary.</p></li>
<li><p>Calls the calculation function(s) using the processed terms in the input
dictionary as input parameters.</p></li>
<li><p>The formatted results content is generated by passing the input dict and any
results produced by the calculation function(s) to the record style’s
buildcontent() method.</p></li>
<li><p>The formatted results content is saved to “results.json”.</p></li>
</ol>
</div>
<div class="section" id="calculation-function-s">
<h4>Calculation function(s)<a class="headerlink" href="#calculation-function-s" title="Permalink to this headline">¶</a></h4>
<p>The calculation functions are listed next, which take Python objects as
arguments.  All results are returned within a dictionary such that the produced
values can be accessed by name.</p>
</div>
<div class="section" id="process-input">
<h4>process_input()<a class="headerlink" href="#process-input" title="Permalink to this headline">¶</a></h4>
<p>The process_input() function is defined next, which processes the string input
values contained within an input dictionary, and assigns default values for any
parameters that were not included in the input.  The processed values either
update the values already in the input dictionary, or are added to the
dictionary as new keys.</p>
<p>The function takes the parameters</p>
<ul class="simple">
<li><p>input_dict: The dictionary of input values to interpret.</p></li>
<li><p>UUID: The UUID4 calculation key to use.  If not given, a new one will be
generated.</p></li>
<li><p>build: A boolean flag, which indicates if the function should build all
objects interpreted from the inputs (True, default), or only those necessary
to define the calculation (False).  Setting build=False allows for
process_input() to be used during high-throughput prepare without the
overhead of creating complex objects that are not used until the calculation
is executed.</p></li>
</ul>
<p>To interpret subset keys similarly across different calculations, use the
Subset.interpret() method for the subset styles you want to include.</p>
<p>For calculation-specific keys, the iprPy.input submodule contains a few
useful functions for interpreting the input files in a common manner.</p>
<ul class="simple">
<li><p>iprPy.input.boolean() will interpret (ignoring case sensitivity) ‘true’,
‘t’, ‘false’, and ‘f’ strings as Python bool values, and will pass
through values that are already bool.</p></li>
<li><p>iprPy.input.value() can be used to interpret and set default values and
units for parameters that may include units information, e.g. “5 nm”.</p></li>
</ul>
</div>
<div class="section" id="main-script-option">
<h4>Main script option<a class="headerlink" href="#main-script-option" title="Permalink to this headline">¶</a></h4>
<p>Finally, the script is told to call the main function if executed directly,
i.e.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="calc-style-in">
<h3>calc_[style].in<a class="headerlink" href="#calc-style-in" title="Permalink to this headline">¶</a></h3>
<p>The included example input file should list all allowed input keys without any
values assigned.  This allows for another user to simply add the values they
want and run the calculation script for themselves.  This example input script
can be automatically generated using XXX if template is defined
for the Calculation subclass.</p>
</div>
<div class="section" id="style-py">
<h3>[Style].py<a class="headerlink" href="#style-py" title="Permalink to this headline">¶</a></h3>
<p>The iprPy package interacts with the calculation style through the defined
Calculation subclass.  Considerable work has gone into making it easy to
define new subclass definitions by modifying values in pre-existing subclass
definitions.  This section describes the different components of defining a
Calculation subclass.</p>
<div class="section" id="inheritance">
<h4>Inheritance<a class="headerlink" href="#inheritance" title="Permalink to this headline">¶</a></h4>
<p>The class should be a child of iprPy.calculation.Calculation.</p>
</div>
<div class="section" id="init">
<h4>__init__()<a class="headerlink" href="#init" title="Permalink to this headline">¶</a></h4>
<p>The __init__() function calls the parent class’ __init__() function and
defines which function from the calculation script to assign to the calc()
method.  Note that the parent Calculation class loads the calculation script as
a module, which can be accessed with self.script.</p>
</div>
<div class="section" id="files">
<h4>files<a class="headerlink" href="#files" title="Permalink to this headline">¶</a></h4>
<p>The files attribute provides a list of the absolute paths to all files
necessary to run the calculation.  If copied from another Calculation subclass,
only the “files” list defined inside the property function should be changed.
This list should be the file names (without path) of the necessary files
besides the calculation script.</p>
</div>
<div class="section" id="template">
<h4>template<a class="headerlink" href="#template" title="Permalink to this headline">¶</a></h4>
<p>The template attribute returns a string template of the input file used by the
calculation script.  If copied from another Calculation subclass, the template
will be automatically generated based on the values in the “subsets” and
“runkeys” lists.  The subsets list gives the names of subsets to include keys
for, while the runkeys list gives the calculation-specific input keys.</p>
</div>
<div class="section" id="singularkeys">
<h4>singularkeys<a class="headerlink" href="#singularkeys" title="Permalink to this headline">¶</a></h4>
<p>The singularkeys attribute lists all prepare input keys recognized by the
calculation that are limited to having single values.  This can be generated by
joining subset keysets with a list of calculation-specific keys.</p>
</div>
<div class="section" id="multi-keys">
<h4>multi keys<a class="headerlink" href="#multi-keys" title="Permalink to this headline">¶</a></h4>
<p>The multikeys attribute lists all sets of prepare input keys recognized by the
calculation that can be assigned multiple values.  The key sets can be
generated by joining subset keysets with lists of calculation-specific keys.</p>
</div>
</div>
<div class="section" id="init-py">
<h3>__init__.py<a class="headerlink" href="#init-py" title="Permalink to this headline">¶</a></h3>
<p>The __init__.py file simply needs to tell Python to include the Calculation
subclass.  For instance, if the subclass is called “Style”, then
__init__.py contains</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">.Style</span> <span class="kn">import</span> <span class="n">Style</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Style&#39;</span><span class="p">]</span>
</pre></div>
</div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Adding new calculation styles</a><ul>
<li><a class="reference internal" href="#files-in-the-calculation-style-directories">Files in the calculation style directories</a><ul>
<li><a class="reference internal" href="#calc-style-py">calc_[style].py</a><ul>
<li><a class="reference internal" href="#record-style">record_style</a></li>
<li><a class="reference internal" href="#main">main()</a></li>
<li><a class="reference internal" href="#calculation-function-s">Calculation function(s)</a></li>
<li><a class="reference internal" href="#process-input">process_input()</a></li>
<li><a class="reference internal" href="#main-script-option">Main script option</a></li>
</ul>
</li>
<li><a class="reference internal" href="#calc-style-in">calc_[style].in</a></li>
<li><a class="reference internal" href="#style-py">[Style].py</a><ul>
<li><a class="reference internal" href="#inheritance">Inheritance</a></li>
<li><a class="reference internal" href="#init">__init__()</a></li>
<li><a class="reference internal" href="#files">files</a></li>
<li><a class="reference internal" href="#template">template</a></li>
<li><a class="reference internal" href="#singularkeys">singularkeys</a></li>
<li><a class="reference internal" href="#multi-keys">multi keys</a></li>
</ul>
</li>
<li><a class="reference internal" href="#init-py">__init__.py</a></li>
</ul>
</li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="addreference.html"
                        title="previous chapter">Reference Library</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="addrecord.html"
                        title="next chapter">Adding new record styles</a></p>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="addrecord.html" title="Adding new record styles"
             >next</a> |</li>
        <li class="right" >
          <a href="addreference.html" title="Reference Library"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="../index.html">iprPy 0.10.2 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="index.html" >Extending iprPy</a> &#187;</li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
      Created using <a href="http://sphinx-doc.org/">Sphinx</a> 2.1.2.
    </div>
  </body>
</html>